
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;
using System.Globalization;

namespace ScrewTurn.Wiki {

	public partial class FileList : System.Web.UI.UserControl {

		private bool canUpload = true, canDelete = true;

		protected void Page_Load(object sender, EventArgs e) {

			btnDeleteSelected.Attributes.Add("onclick", "javascript:return __ConfirmOperation();");
			btnRename.Attributes.Add("onclick", "javascript:return __ConfirmOperation();");

			if(SessionFacade.LoginKey != null) {
				// Registered User
				if(!SessionFacade.Admin) {
					// Check permissions
					canUpload = Settings.UsersCanUploadFiles;
					canDelete = Settings.UsersCanDeleteFiles;
				}
				// Else: Users is Admin, can do any operation
			}
			else {
				// Anonymous User
				if(!Settings.FileManagementInPublicAccessAllowed) {
					// Disable all modifications
					canUpload = false;
					canDelete = false;
				}
				else {
					// Check permissions
					canUpload = Settings.UsersCanUploadFiles;
					canDelete = Settings.UsersCanDeleteFiles;
				}
			}

			// Setup buttons and controls
			if(!canUpload) {
				updFile.Visible = false;
				btnUpload.Visible = false;
				lblResult.Visible = false;
				chkOverwrite.Visible = false;
				txtNewDirectory.Visible = false;
				btnNewDirectory.Visible = false;
			}
			if(!canDelete) {
				chkOverwrite.Visible = false;
				btnDeleteSelected.Visible = false;
			}

			if(Request["CD"] != null && !Page.IsPostBack) {
				if(Request["CD"].Equals("..")) {
					if(txtCurrentDirectory.Value.IndexOf("\\") != -1) {
						txtCurrentDirectory.Value = txtCurrentDirectory.Value.Substring(0, txtCurrentDirectory.Value.LastIndexOf("\\"));
					}
					else {
						txtCurrentDirectory.Value = "";
					}
				}
				else {
					txtCurrentDirectory.Value = Request["CD"];
				}
			}

			captcha.Visible = SessionFacade.LoginKey == null && !Settings.DisableCaptchaControl;

			PrintInfo();
			PrintStrings();
			PrintFileList();
		}

		private bool showLink = false;
		[DefaultSettingValue("False")]
		public bool ShowLink {
			get { return showLink; }
			set { showLink = value; }
		}

		private int listHeight = -1;
		[DefaultSettingValue("-1")]
		public int ListHeight {
			get { return listHeight; }
			set { listHeight = value; }
		}

		private bool printInformation = true;
		[DefaultSettingValue("True")]
		public bool PrintInformation {
			get { return printInformation; }
			set { printInformation = value; }
		}

		public void PrintStrings() {
			StringBuilder sb = new StringBuilder();
			sb.Append(@"<script type=""text/javascript"">" + "\n<!--\n");
			sb.Append("var __ConfirmMessage = '");
			sb.Append(Resources.Messages.ConfirmOperation);
			sb.Append("';\n");
			sb.Append("// -->\n</script>\n");
			lblStrings.Text = sb.ToString();
		}

		public void PrintInfo() {
			if(!printInformation) return;
			StringBuilder sb = new StringBuilder();
			sb.Append(@"<p class=""small"">");
			string[] allowedFileTypes = Settings.AllowedFileTypes;
			sb.Append("<b>");
			sb.Append(Resources.Messages.AllowedFileTypes);
			sb.Append("</b>: ");
			for(int i = 0; i < allowedFileTypes.Length; i++) {
				sb.Append(allowedFileTypes[i].ToUpperInvariant());
				if(i != allowedFileTypes.Length - 1) sb.Append(", ");
			}
			sb.Append("</p><br />");
			lblInfo.Text = sb.ToString();
		}

		public void PrintLink() {
			if(!showLink) return;

			Response.Write(@"<small><a href=""Upload.aspx"" target=""_blank"">");
			Response.Write(Resources.Messages.ExtendedInterface);
			Response.Write("</a></small>");
		}

		public void PrintFileList() {
			StringBuilder sb = new StringBuilder();
			if(listHeight > 0) {
				sb.Append(@"<div style=""height: ");
				sb.Append(listHeight.ToString());
				sb.Append(@"px; overflow: scroll;"">");
			}

			sb.Append(@"<table id=""FileListTable"" cellpadding=""2"" cellspacing=""0"">");

			sb.Append(@"<tr id=""FileListHeader"">");
			if(canDelete) sb.Append(@"<td width=""16""><img src=""Images/Trash.png"" alt=""Trash"" /></td>");
			if(canDelete && canUpload) sb.Append(@"<td width=""16"">&nbsp;</td>");
			sb.Append(@"<td width=""18"">&nbsp;</td>");
			sb.Append("<td><p><b>");
			sb.Append(Resources.Messages.Name);
			sb.Append("</b></p></td>");
			sb.Append("<td><p><b>");
			sb.Append(Resources.Messages.Size);
			sb.Append("</b></p></td>");
			sb.Append("<td><p><b>");
			sb.Append(Resources.Messages.Link);
			sb.Append("</b></p></td>");
			sb.Append("</tr>");

			int count = 0;
			if(txtCurrentDirectory.Value.Length > 0) {
				count++;
				sb.Append("<tr>");
				if(canDelete) sb.Append(@"<td width=""16"" class=""filelistcelleven"">&nbsp;</td>");
				if(canDelete && canUpload) sb.Append(@"<td width=""16"" class=""filelistcelleven"">&nbsp;</td>");
				sb.Append(@"<td width=""18"" class=""filelistcelleven"">" + @"<img src=""Images/Up.png"" alt=""Up"" />" + "</td>");
				sb.Append(@"<td class=""filelistcelleven""><p><a href=""Upload.aspx?CD=");
				sb.Append((txtCurrentDirectory.Value.IndexOf("\\") != -1 ? txtCurrentDirectory.Value.Substring(0, txtCurrentDirectory.Value.LastIndexOf("\\")) : ""));
				sb.Append(@"""><b>..</b></a></p></td>");
				sb.Append(@"<td class=""filelistcelleven"">&nbsp;</td><td class=""filelistcelleven"">&nbsp;</td>");
				sb.Append("</tr>");
			}

			// Dir list
			string[] dirs = Directory.GetDirectories(Settings.UploadDirectory + txtCurrentDirectory.Value);
			DirectoryInfo dirInfo;
			string tmp;
			for(int i = 0; i < dirs.Length; i++) {
				dirInfo = new DirectoryInfo(dirs[i]);
				sb.Append("<tr>");
				tmp = ((i + count) % 2 != 0 ? "odd" : "even");
				if(canDelete) {
					sb.Append(@"<td width=""16"" class=""filelistcell");
					sb.Append(tmp);
					sb.Append(@""">");
					sb.Append(@"<input type=""checkbox"" name=""DeleteDir|");
					sb.Append(Tools.UrlEncode(dirInfo.FullName.Substring(Settings.UploadDirectory.Length)));
					sb.Append(@""" />");
					sb.Append("</td>");

					if(canUpload) {
						sb.Append(@"<td width=""16"" class=""filelistcell");
						sb.Append(tmp);
						sb.Append(@""">");
						sb.Append(@"<a href=""#"" onclick=""javascript:return __PrepareRename('");
						sb.Append(dirInfo.Name);
						sb.Append(@"', 'DIRECTORY');"" title=""");
						sb.Append(Resources.Messages.RenameThisItem);
						sb.Append(@"""><img src=""Images/Rename.png"" alt=""R"" /></a>");
						sb.Append("</td>");
					}
				}
				sb.Append(@"<td width=""18"" class=""filelistcell");
				sb.Append(tmp);
				sb.Append(@""">");
				sb.Append(@"<img src=""Images/Dir.png"" alt=""Dir"" />");
				sb.Append("</td>");
				sb.Append(@"<td class=""filelistcell");
				sb.Append(tmp);
				sb.Append(@"""><p><a href=""Upload.aspx?CD=");
				sb.Append(Tools.UrlEncode(dirInfo.FullName.Substring(Settings.UploadDirectory.Length)));
				sb.Append(@""">");
				sb.Append(dirInfo.Name);
				sb.Append("</a></p></td>");
				sb.Append(@"<td class=""filelistcell");
				sb.Append(tmp);
				sb.Append(@""">(");
				sb.Append(dirInfo.GetFileSystemInfos().Length.ToString());
				sb.Append(@")</td><td class=""filelistcell");
				sb.Append(tmp);
				sb.Append(@""">&nbsp;</td>");
				sb.Append("</tr>");
			}
			count += dirs.Length;

			// File list
			string[] files = Directory.GetFiles(Settings.UploadDirectory + txtCurrentDirectory.Value);
			FileInfo info;
			for(int i = 0; i < files.Length; i++) {
				info = new FileInfo(files[i]);
				sb.Append(@"<tr>");
				tmp = ((i + count) % 2 != 0 ? "odd" : "even");
				if(canDelete) {
					sb.Append(@"<td width=""16"" class=""filelistcell");
					sb.Append(tmp);
					sb.Append(@""">");
					sb.Append(@"<input type=""checkbox"" name=""DeleteFile|");
					sb.Append(Tools.UrlEncode(info.FullName.Substring(Settings.UploadDirectory.Length)));
					sb.Append(@""" />");
					sb.Append("</td>");

					if(canUpload) {
						sb.Append(@"<td width=""16"" class=""filelistcell");
						sb.Append(tmp);
						sb.Append(@""">");
						sb.Append(@"<a href=""#"" onclick=""javascript:return __PrepareRename('");
						sb.Append(info.Name);
						sb.Append(@"', 'FILE');"" title=""");
						sb.Append(Resources.Messages.RenameThisItem);
						sb.Append(@"""><img src=""Images/Rename.png"" alt=""R"" /></a>");
						sb.Append("</td>");
					}
				}
				sb.Append(@"<td width=""18"" class=""filelistcell");
				sb.Append(tmp);
				sb.Append(@"""><img src=""Images/File.png"" alt=""File"" /></td>");
				sb.Append(@"<td class=""filelistcell");
				sb.Append(tmp);
				sb.Append(@"""><p><a href=""GetFile.aspx?File=");
				sb.Append(Tools.UrlEncode(info.FullName.Substring(Settings.UploadDirectory.Length)));
				sb.Append(@""">");
				sb.Append(info.Name);
				sb.Append("</a></p></td>");
				sb.Append(@"<td class=""filelistcell");
				sb.Append(tmp);
				sb.Append(@"""><p>");
				sb.Append(Tools.BytesToString(info.Length));
				sb.Append("</p></td>");
				sb.Append(@"<td class=""filelistcell");
				sb.Append(tmp);
				sb.Append(@"""><p>{UP}");
				sb.Append(Tools.UrlEncode(info.FullName.Substring(Settings.UploadDirectory.Length).Replace("\\", "/")));
				sb.Append("</p></td>");
				sb.Append("</tr>");
			}

			sb.Append("</table>");

			if(listHeight > 0) sb.Append("</div>");

			lblFileList.Text = sb.ToString();
		}

		protected void btnUpload_Click(object sender, EventArgs e) {
			if(!Page.IsValid) return;
			if(!canUpload) return;
			lblResult.Text = "";
			if(!updFile.HasFile) {
				lblResult.CssClass = "resulterror";
				lblResult.Text = Resources.Messages.FileVoid;
				return;
			}
			if(File.Exists(Settings.UploadDirectory + txtCurrentDirectory.Value + "\\" + updFile.FileName) && !chkOverwrite.Checked) {
				lblResult.CssClass = "resulterror";
				lblResult.Text = Resources.Messages.FileAlreadyExists;
				return;
			}
			string[] allowedFileTypes = Settings.AllowedFileTypes;
			bool found = false;
			for(int i = 0; i < allowedFileTypes.Length; i++) {
				if(Path.GetExtension(updFile.FileName).ToLower(CultureInfo.CurrentCulture).Equals("." + allowedFileTypes[i].ToLower(CultureInfo.CurrentCulture))) {
					found = true;
					break;
				}
			}
			if(!found) {
				Log.LogEntry("Unallowed file type upload attempt blocked (" + Path.GetExtension(updFile.FileName) + ")", EntryType.Warning, SessionFacade.Username);
				lblResult.CssClass = "resulterror";
				lblResult.Text = Resources.Messages.UnallowedFileType;
				return;
			}
			if(updFile.FileBytes.Length > Settings.MaxFileSize * 1024) {
				Log.LogEntry("File too big (" + updFile.FileBytes.Length.ToString() + ")", EntryType.Warning, SessionFacade.Username);
				lblResult.CssClass = "resulterror";
				lblResult.Text = Resources.Messages.FileTooBig;
				return;
			}
			// Delete cached thumbnails (if any)
			Tools.DeleteThumbnails(txtCurrentDirectory.Value + "\\" + updFile.FileName);
			updFile.SaveAs(Settings.UploadDirectory + txtCurrentDirectory.Value + "\\" + updFile.FileName);
			lblResult.CssClass = "resultok";
			lblResult.Text = Resources.Messages.FileSaved;
			Log.LogEntry("File " + updFile.FileName + " uploaded", EntryType.General, SessionFacade.Username);
			PrintFileList();
		}

		protected void btnNewDirectory_Click(object sender, EventArgs e) {
			if(!canUpload) return;
			if(txtNewDirectory.Text.Replace(" ", "").Length == 0) {
				return;
			}

			try {
				Directory.CreateDirectory(Settings.UploadDirectory + txtCurrentDirectory.Value + "\\" + txtNewDirectory.Text);
				lblResult.CssClass = "resultok";
				lblResult.Text = Resources.Messages.DirectoryCreated;
				txtNewDirectory.Text = "";
			}
			catch { }
			PrintFileList();
		}

		protected void btnDeleteSelected_Click(object sender, EventArgs e) {
			if(!Page.IsValid) return;
			if(!canDelete) return;
			// Delete Directories
			for(int i = 0; i < Request.Params.AllKeys.Length; i++) {
				if(Request.Params.AllKeys[i].StartsWith("DeleteDir|")) {
					string dir = Server.UrlDecode(Request.Params.AllKeys[i].Substring("DeleteDir|".Length));
					//Response.Write("Delete: " + dir + "<br />");
					Directory.Delete(Settings.UploadDirectory + dir, true);
					lblResult.CssClass = "resultok";
					lblResult.Text = Resources.Messages.DirectoryDeleted;
				}
			}

			// Delete Files
			for(int i = 0; i < Request.Params.AllKeys.Length; i++) {
				if(Request.Params.AllKeys[i].StartsWith("DeleteFile|")) {
					string file = Server.UrlDecode(Request.Params.AllKeys[i].Substring("DeleteFile|".Length));
					//Response.Write("Delete: " + file + "<br />");
					File.Delete(Settings.UploadDirectory + file);
					lblResult.CssClass = "resultok";
					lblResult.Text = Resources.Messages.FileDeleted;
				}
			}
			PrintFileList();
		}

		public void PrintFileExtensions() {
			string[] ext = Settings.AllowedFileTypes;
			Response.Write("var __message = \"");
			Response.Write(Resources.Messages.InvalidFileType);
			Response.Write("\";\n");
			Response.Write("var __ext = new Array(");
			Response.Write(ext.Length.ToString());
			Response.Write(");\n");
			for(int i = 0; i < ext.Length; i++) {
				Response.Write("__ext[");
				Response.Write(i.ToString());
				Response.Write("] = \"");
				Response.Write(ext[i]);
				Response.Write("\";\n");
			}
		}

		protected void btnRename_Click(object sender, EventArgs e) {
			if(!Page.IsValid) return;
			if(!canUpload || !canDelete) return;

			bool err = false;

			switch(txtItemType.Value.ToLowerInvariant()) {
				case "file":
					string filename = txtNewName.Text.Trim();
					if(filename.Length == 0) {
						lblResult.CssClass = "resulterror";
						lblResult.Text = Resources.Messages.InvalidFileName;
						err = true;
					}
					else {
						if(!Path.GetExtension(filename).Equals(Path.GetExtension(txtOldName.Value))) filename += Path.GetExtension(txtOldName.Value);
						if(File.Exists(Settings.UploadDirectory + txtCurrentDirectory.Value + "\\" + filename)) {
							lblResult.CssClass = "resulterror";
							lblResult.Text = Resources.Messages.FileAlreadyExists;
							err = true;
						}
						else {
							try {
								File.Move(Settings.UploadDirectory + txtCurrentDirectory.Value + "\\" + txtOldName.Value, Settings.UploadDirectory + txtCurrentDirectory.Value + "\\" + filename);
								// Delete cached thumbnails (if any)
								Tools.DeleteThumbnails(txtCurrentDirectory.Value + "\\" + filename);
								lblResult.CssClass = "resultok";
								lblResult.Text = Resources.Messages.FileRenamed;
							}
							catch {
								lblResult.CssClass = "resulterror";
								lblResult.Text = Resources.Messages.FileRenamingError;
								err = true;
							}
						}
					}
					break;
				case "directory":
					string dirname = txtNewName.Text.Trim();
					if(dirname.Length == 0) {
						lblResult.CssClass = "resulterror";
						lblResult.Text = Resources.Messages.InvalidDirectoryName;
						err = true;
					}
					else {
						if(Directory.Exists(Settings.UploadDirectory + txtCurrentDirectory.Value + "\\" + dirname)) {
							lblResult.CssClass = "resulterror";
							lblResult.Text = Resources.Messages.DirectoryAlreadyExists;
							err = true;
						}
						else {
							try {
								Directory.Move(Settings.UploadDirectory + txtCurrentDirectory.Value + "\\" + txtOldName.Value, Settings.UploadDirectory + txtCurrentDirectory.Value + "\\" + dirname);
								lblResult.CssClass = "resultok";
								lblResult.Text = Resources.Messages.DirectoryRenamed;
							}
							catch {
								lblResult.CssClass = "resulterror";
								lblResult.Text = Resources.Messages.DirectoryRenamingError;
								err = true;
							}
						}
					}
					break;
			}

			PrintFileList();

			if(err) {
				lblExpandRename.Text = @"<script type=""text/javascript""><!--" + "\n" + "document.getElementById('ItemRenameDiv').style['display'] = '';" + "\n" + "// -->\n</script>\n";
			}
			else lblExpandRename.Text = "";
		}

	}

}
